using System.Web.Mvc;
using ETestIT.Core;
using ETestIT.Core.DataInterfaces;
using MvcContrib.Pagination;
using SharpArch.Core.PersistenceSupport;
using SharpArch.Core.DomainModel;
using System.Collections.Generic;
using System;
using SharpArch.Core.PersistenceSupport.NHibernate;
using SharpArch.Web.NHibernate;
using NHibernate.Validator.Engine;
using System.Text;
using SharpArch.Web.CommonValidator;
using SharpArch.Core;

namespace ETestIT.Web.Controllers
{
    [HandleError]
    public class CandidatesController : Controller
    {
        public CandidatesController(ICandidateRepository candidateRepository, IRepository<JobTitle> jobTitlesRepository)
        {
            Check.Require(candidateRepository != null, "candidateRepository may not be null");
            Check.Require(jobTitlesRepository != null, "jobTitlesRepository may not be null");

            this.candidateRepository = candidateRepository;
            this.jobTitlesRepository = jobTitlesRepository;
        }

        [Transaction]
        public ActionResult Index(int? page)
        {
            var candidates = candidateRepository.GetAll().AsPagination(page ?? 1, 20);
            return View(candidates);
        }

        [Transaction]
        public ActionResult Show(int id)
        {
            Candidate candidate = candidateRepository.Get(id);
            return View(candidate);
        }

        public ActionResult Create()
        {
            CandidateFormViewModel viewModel = CandidateFormViewModel.CreateCandidateFormViewModel(jobTitlesRepository);
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Candidate candidate)
        {
            if (ViewData.ModelState.IsValid && candidate.IsValid())
            {
                candidate.RecrutedBy = User.Identity.Name;
                candidateRepository.SaveOrUpdate(candidate);

                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] =
                    "The candidate was successfully created.";
                return RedirectToAction("Index");
            }

            CandidateFormViewModel viewModel = CandidateFormViewModel.CreateCandidateFormViewModel(jobTitlesRepository);
            viewModel.Candidate = candidate;
            return View(viewModel);
        }

        [Transaction]
        public ActionResult Edit(int id)
        {
            CandidateFormViewModel viewModel = CandidateFormViewModel.CreateCandidateFormViewModel(jobTitlesRepository);
            viewModel.Candidate = candidateRepository.Get(id);
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Candidate candidate)
        {
            Candidate candidateToUpdate = candidateRepository.Get(candidate.Id);
            TransferFormValuesTo(candidateToUpdate, candidate);

            if (ViewData.ModelState.IsValid && candidate.IsValid())
            {
                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] =
                    "The candidate was successfully updated.";
                return RedirectToAction("Index");
            }
            else
            {
                candidateRepository.DbContext.RollbackTransaction();

                CandidateFormViewModel viewModel = CandidateFormViewModel.CreateCandidateFormViewModel(jobTitlesRepository);
                viewModel.Candidate = candidate;
                return View(viewModel);
            }
        }

        private void TransferFormValuesTo(Candidate candidateToUpdate, Candidate candidateFromForm)
        {
            candidateToUpdate.FirstName = candidateFromForm.FirstName;
            candidateToUpdate.Surename = candidateFromForm.Surename;
            candidateToUpdate.Email = candidateFromForm.Email;
            candidateToUpdate.Phone = candidateFromForm.Phone;
            candidateToUpdate.Category = candidateFromForm.Category;
            candidateToUpdate.ProfileTitle = candidateFromForm.ProfileTitle;
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id)
        {
            string resultMessage = "The candidate was successfully deleted.";
            Candidate candidateToDelete = candidateRepository.Get(id);

            if (candidateToDelete != null)
            {
                candidateRepository.Delete(candidateToDelete);

                try
                {
                    candidateRepository.DbContext.CommitChanges();
                }
                catch
                {
                    resultMessage = "A problem was encountered preventing the candidate from being deleted. " +
                        "Another item likely depends on this candidate.";
                    candidateRepository.DbContext.RollbackTransaction();
                }
            }
            else
            {
                resultMessage = "The candidate could not be found for deletion. It may already have been deleted.";
            }

            TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = resultMessage;
            return RedirectToAction("Index");
        }

        /// <summary>
        /// Holds data to be passed to the Candidate form for creates and edits
        /// </summary>
        public class CandidateFormViewModel
        {
            private CandidateFormViewModel() { }

            /// <summary>
            /// Creation method for creating the view model. Services may be passed to the creation 
            /// method to instantiate items such as lists for drop down boxes.
            /// </summary>
            public static CandidateFormViewModel CreateCandidateFormViewModel(IRepository<JobTitle> jobTitlesRepository)
            {
                return new CandidateFormViewModel { Titles = jobTitlesRepository.GetAll() };
            }

            public Candidate Candidate { get; internal set; }
            public IList<JobTitle> Titles { get; internal set; }
        }

        private readonly ICandidateRepository candidateRepository;
        private readonly IRepository<JobTitle> jobTitlesRepository;

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Search()
        {
            return View("Index");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Search(string firstName, string surename, string email, string phone)
        {
            var candidateExample = new Candidate();

            if (!string.IsNullOrEmpty(firstName))
                candidateExample.FirstName = firstName.Trim();

            if (!string.IsNullOrEmpty(surename))
                candidateExample.Surename = surename.Trim();

            if (!string.IsNullOrEmpty(email))
                candidateExample.Email = email.Trim();

            if (!string.IsNullOrEmpty(phone))
                candidateExample.Phone = phone.Trim();

            var result = candidateRepository.SearchByExample(candidateExample).AsPagination(1, 80);

            return View("Index", result);
        }

    }
}
